<script setup>
import { number } from 'echarts';
import { onMounted, ref, defineExpose } from 'vue';
const shapeInfoList = ref([]);
defineExpose({shapeInfoList})
// 获取svg元素宽高
const mainSvg = ref(null);
onMounted(() => {
  if (mainSvg.value) {
    const width = mainSvg.value.clientWidth;
    const height = mainSvg.value.clientHeight;
    console.log(`Width: ${width}, Height: ${height}`);
  }
})
shapeInfoList.value = [
  {
    id: '1',
    modelName: '', //名字
    bounds: {
      width: 200,  // 宽
      height: 100,  // 高
      absx: 50,  // X轴位置
      absy: 50,  // Y轴位置
    },
    style: {
      rx: '10',   // 横轴弯曲度
      ry: '10',  // 纵轴弯曲度
      fill: '#fff',  // 背景色 或别的
      stroke: '#000',  // 边框颜色
      strokeWidth: '2',  // 边框宽度
    },
    lineId: '3',
    type: 'model'
  },

  {
    id: '2',
    bounds: {
      width: 200,  // 宽
      height: 100,  // 高
      absx: 500,  // X轴位置
      absy: 50,  // Y轴位置
    },
    style: {
      rx: '10',   // 横轴弯曲度
      ry: '10',  // 纵轴弯曲度
      fill: '#fff',  // 背景色 或别的
      stroke: '#000',  // 边框颜色
      strokeWidth: '2',  // 边框宽度
    },
    lineId: '3',
    type: 'model'
  },

  {
    id: '3',
    bounds: {
      width: '',  // 宽
      height: '',  // 高
      absx: '',  // X轴位置
      absy: '',  // Y轴位置
    },
    style: {
      rx: '',   // 横轴弯曲度
      ry: '',  // 纵轴弯曲度
      fill: '',  // 背景色 或别的
      stroke: '',  // 边框颜色
      strokeWidth: '',  // 边框宽度
    },
    wayPoint: [{ x:250, y:100 }, {x:500, y: 100}],  // 处理中间点位
    sourceId: '1', // 关联的源端图形
    targetId: '2',  //  关联的尾端图形
    type: 'line'
  }
]

// 初始化数据处理
onMounted (() => {
  shapeInfoList.value.forEach(item => {
    if(item.type == 'line'){
      item.d = handleMountedLine(item);
    }
  })
})

// 初始化线段处理
const handleMountedLine = (line) => {
  // 根据点位生成路径
  let d = [];
  line.wayPoint.forEach((item, index) => {
    if(index == 0){
      d.push(`M${item.x},${item.y}`)
    }else {
      d.push(`L${item.x},${item.y}`)
    }
  })
  return d.join(',')
}
// 当前双击ID
let currId = '';
// 控制编辑edit
const editable = ref(false); 
// 文本变量
let text = '';

// 处理单击
const handleDblclick = (shape) => {
  currId = shape.id;
  editable.value = true;
}

// 处理输入
const handleInput = (e) => {
  text = e.target.innerHTML;
}

// 处理保存名字
const handleSave = () => {
  editable.value = false;
  const index = shapeInfoList.value.findIndex(item => {return item.id == currId});
  shapeInfoList.value[index].modelName = text;
}

// 画布点击 清除当前选中,或者选中当前点击元素
const handleClickSvg = (event) => {
  if(event.target.localName == 'svg'){
    currMouseId.value = null;
    isCurrFlag.value = false;
    currShape.value = null;
  }else {
    currMouseId.value = event.target.id;
    isCurrFlag.value = true;
    const index = shapeInfoList.value.findIndex(item => {return item.id == currMouseId.value});
    currShape.value = JSON.parse(JSON.stringify(shapeInfoList.value[index]));
  }
  
}

// 监听鼠标事件变量
const dragFlag = ref(false);

const currMouseId = ref('');
// 当前选中元素
const currShape = ref(null);
// 是否选中
const isCurrFlag = ref(false);

let initialX = 0;
let initialY = 0;
const deltaX = ref(0);
const deltaY = ref(0);

const handleMouseDownSvg = (event) => {
  if(event.target.localName == 'svg'){
    currMouseId.value = null;
    isCurrFlag.value = false;
    currShape.value = null;
    dragFlag.value = false;
  }else {
    currMouseId.value = event.target.id;
    isCurrFlag.value = true;
    const index = shapeInfoList.value.findIndex(item => {return item.id == currMouseId.value});
    currShape.value = shapeInfoList.value[index];
    dragFlag.value = true;
  }
  
}
// 鼠标移动 这里不监听div鼠标移动主要因为鼠标会移动出去
// 不能实时移动div因为svg会闪烁
const handleMousemoveSvg = (event)=> {
  // 画布鼠标移动
  if(dragFlag.value || sizeFlag.value){
    const {clientX,offsetX, clientY,offsetY} = event;
    if(initialX == 0 && initialY == 0){
      initialX = clientX;
      initialY = clientY;
    }else {
      deltaX.value = event.clientX - initialX;
      deltaY.value = event.clientY - initialY;
    }
  }
}

const handleMouseupSvg = (event) => {
  
  if(dragFlag.value){
    
    const index = shapeInfoList.value.findIndex(item => {return item.id == currMouseId.value});
    
    shapeInfoList.value[index].bounds.absx = shapeInfoList.value[index].bounds.absx + deltaX.value;
    shapeInfoList.value[index].bounds.absy = shapeInfoList.value[index].bounds.absy + deltaY.value;
    if(shapeInfoList.value[index].lineId){
      handleModelLineMove(shapeInfoList.value[index].lineId, shapeInfoList.value[index].id, deltaX.value, deltaY.value);
    }
  }
  if(sizeFlag.value){
    const index = shapeInfoList.value.findIndex(item => {return item.id == currMouseId.value});
    if(deltaX.value > 0){
      shapeInfoList.value[index].bounds.width = shapeInfoList.value[index].bounds.width - deltaX.value;
    }else {
      shapeInfoList.value[index].bounds.width = shapeInfoList.value[index].bounds.width + Math.abs(deltaX.value);
    }
    if(deltaY.value > 0){
      shapeInfoList.value[index].bounds.height = shapeInfoList.value[index].bounds.height - Math.abs(deltaY.value);
    }else {
      shapeInfoList.value[index].bounds.height = shapeInfoList.value[index].bounds.height + Math.abs(deltaY.value);
    }
    shapeInfoList.value[index].bounds.absx = shapeInfoList.value[index].bounds.absx + deltaX.value;
    shapeInfoList.value[index].bounds.absy = shapeInfoList.value[index].bounds.absy + deltaY.value;
  }  
  dragFlag.value = false;
  sizeFlag.value = false;
  initialX = 0;
  initialY = 0;
  deltaX.value = 0;
  deltaY.value = 0;
  currMouseId.value = '';
}

// 处理拖拽图形后的线移动
const handleModelLineMove = (lineId, rectId, x, y)=>{
  console.log(lineId, rectId)
  let line =  shapeInfoList.value[shapeInfoList.value.findIndex(item => {return item.id == lineId})];
  let rect = shapeInfoList.value[shapeInfoList.value.findIndex(item => {return item.id == rectId})];
  console.log(line)
  console.log(rect)
  if(rectId == line.targetId){
    let point = line.wayPoint[line.wayPoint.length - 1];
    line.wayPoint[line.wayPoint.length - 1] = {x: point.x + x, y: point.y + y}
  }else {
    let point = line.wayPoint[0];
    line.wayPoint[0] = {x: point.x + x, y: point.y + y}
  }

  console.log(line.wayPoint)
  line.d = handleMountedLine(line)
}
// 设置大小
const sizeFlag = ref(false);
const handleSizeMouseDown = (event, type, id) => {
  dragFlag.value = false;
  sizeFlag.value = true;
  currMouseId.value = id;
  const index = shapeInfoList.value.findIndex(item => {return item.id == currMouseId.value});
  currShape.value = shapeInfoList.value[index];
}

const eventHandler = (event) => {

}
</script>

<template>
  <div class="graph-view" ref="viewDom">
    <!-- 画布层svg -->
    <svg width="100%" height="80vh" ref="mainSvg" 
      @mousemove="handleMousemoveSvg" 
      @mouseup="handleMouseupSvg"
      @click="handleClickSvg"
      @mousedown="handleMouseDownSvg">
      <g style="width: 100%; height: 100%; background-color: white;">
        
        <!-- 白色背景色 -->
        <rect width="100%" height="100%" 
          fill="#fff" style="pointer-events:none">
        </rect>

        <!-- 网格图 -->
        <rect width="100%" height="100%" 
          fill="url(#flow_canvas_grid_item)" style="pointer-events:none">
        </rect>

        <defs>
          <pattern id="flow_canvas_grid_item" width="61" height="61" patternUnits="userSpaceOnUse">
            <path id="flow_canvas_grid_path1" stroke-width="1" fill="none"
              d="M0 15L60 15M15 0L15 60M0 30L60 30M30 0L30 60M0 45L60 45M45 0L45 60" stroke="rgb(242,242,242)"></path>
            <path id="flow_canvas_grid_path2" stroke-width="1" fill="none" d="M0 60L60 60M60 0L60 60"
              stroke="rgb(229,229,229)"></path>
          </pattern>
          <pattern xmlns="http://www.w3.org/2000/svg" patternUnits="userSpaceOnUse" id="flow_canvas_watermark_item"
            width="300" height="300">
            <text x="150" y="100" font-size="18" transform="rotate(-45, 150, 150)"
              style="dominant-baseline: middle; text-anchor: middle;"></text>
          </pattern>

          <marker id="arrow" markerWidth="10" markerHeight="10" refX="5" refY="3" orient="auto" markerUnits="strokeWidth">
            <!-- <path d="M0,0 L0,6 L9,3 z" fill="black"/> -->
             <path d="M0,0 L0, 10 L10,5 z"></path>
          </marker>
        </defs>
        <g >
          <g v-for="shape in shapeInfoList" :key="shape.id" 
           
            >
            <!-- 实际dom -->
            <rect v-if="shape.type=='model'"
              :id="shape.id"
              :width="shape.bounds.width" 
              :height="shape.bounds.height" 
              :rx="shape.style.rx" 
              :ry="shape.style.rx" 
              :x="shape.bounds.absx" 
              :y="shape.bounds.absy" 
              :fill="shape.style.fill" 
              :stroke="shape.style.stroke" 
              :stroke-width="shape.style.strokeWidth"
              >
            </rect>
            
            <path v-if="shape.type=='line'" :d="shape.d" fill="none"  stroke="#000" stroke-linejoin="round" marker-end="url(#arrow)"></path>
            <!-- 设置名字 -->
            <!-- <foreignObject  :width="shape.bounds.width" :height="shape.bounds.height" :x="shape.bounds.absx" :y="shape.bounds.absy">
              <div  class="textarea" ref="input" :contenteditable="editable" @input="handleInput" @blur="handleSave">
                {{ shape.modelName }}
              </div>
            </foreignObject> -->
          </g>
          <!-- <path d="M250,100 L500,100" fill="none"  stroke="#000" stroke-linejoin="round" marker-end="url(#arrow)"></path> -->
        </g>
      </g>
    </svg>
    
    <!-- 交互层 设置了pointer-events， 元素永远不会成为鼠标事件的target。其后端元素可以捕获-->
    <svg width="100%" height="80vh" ref="mainSvg2" style=" position: absolute; top: 12px; left: 12px; pointer-events: none;">
      <g v-if="isCurrFlag">
        <!-- 拖拽层 -->
        <rect v-if="dragFlag" style="pointer-events: none;" :transform="`translate(${deltaX},${deltaY})`" 
          :width="currShape.bounds.width" :height="currShape.bounds.height" 
          :rx="currShape.style.rx" :ry="currShape.style.rx" 
          :x="currShape.bounds.absx" :y="currShape.bounds.absy" 
          :fill="currShape.style.fill" :stroke="currShape.style.stroke" 
          :stroke-width="currShape.style.strokeWidth" stroke-opacity="0.5"></rect>
        <!-- 尺寸层 -->
        <g style="pointer-events: all;" @mouseup.stop @mousemove.stop>
          <rect :width="8" 
            :height="8" 
            :x="currShape.bounds.absx + deltaX" 
            :y="currShape.bounds.absy + deltaY" 
            fill="#fff"
            stroke-width="1"
            stroke="rgb(6, 123, 239)"
            :transform="`translate(${-6},${-6})`"
            cursor="nw-resize"
            @mousedown="handleSizeMouseDown($event, 1, currShape.id)" @mouseup.stop @mousemove.stop
            ></rect>
          <!-- 尺寸大小层 -->
          <rect v-if="sizeFlag" style="pointer-events: none;"
            :width="currShape.bounds.width - deltaX" :height="currShape.bounds.height - deltaY" 
            :rx="currShape.style.rx" :ry="currShape.style.rx" 
            :x="currShape.bounds.absx + deltaX" :y="currShape.bounds.absy + deltaY" 
            :fill="currShape.style.fill" 
            :stroke="currShape.style.stroke" :stroke-width="currShape.style.strokeWidth" stroke-opacity="0.5"></rect>
        </g>
      </g>
    </svg>
  </div>
  
</template>

<style scoped>
.graph-view {
  position: relative;
  padding: 12px;
  width: 80%;
}

.textarea {
  display: flex;
  flex-direction: column;
  justify-content: center;
  outline-color: transparent;
  /* 设置光标颜色 */
  caret-color: rgb(0, 0, 0);
  user-select: none;
  text-align: center;
  word-break: break-all;
  width: 100%;
  height: 100%;
}

</style>